package com.atguigu.ssyx.acl.service.impl;

import com.atguigu.ssyx.ServiceAclApplication;
import com.atguigu.ssyx.acl.mapper.PermissionMapper;
import com.atguigu.ssyx.acl.service.PermissionService;
import com.atguigu.ssyx.acl.service.RolePermissionService;
import com.atguigu.ssyx.acl.utils.PermissionHelper;
import com.atguigu.ssyx.model.acl.Permission;
import com.atguigu.ssyx.model.acl.RolePermission;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {

    private static final Logger logger = LoggerFactory.getLogger(ServiceAclApplication.class.getName());

    @Resource
    private RolePermissionService rolePermissionService;

    /**
     * 查询所有菜单权限
     * @return
     */
    @Override
    public List<Permission> queryAllPermission() {
        // 查询所有菜单权限，根据id升序
        LambdaQueryWrapper<Permission> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByAsc(Permission::getId);
        List<Permission> permissionList = baseMapper.selectList(wrapper);
        // 转换要求的数据格式
        return PermissionHelper.buildPermission(permissionList);
    }

    /**
     * 删除菜单权限
     * @param id
     * @return
     */
    @Override
    public void removeChildById(Long id) {
        List<Long> idList = new ArrayList<>();
        // 递归查找当前菜单的子菜单
        this.findChildren(id, idList);
        // 设置当前菜单权限id
        idList.add(id);
        baseMapper.deleteBatchIds(idList);
    }

    // 递归查找当前菜单的子菜单
    private void findChildren(Long id, List<Long> idList) {
        LambdaQueryWrapper<Permission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Permission::getPid, id);
        List<Permission> childList = baseMapper.selectList(wrapper);
        childList.forEach(item -> {
            idList.add(item.getId());
            // 递归
            this.findChildren(item.getId(), idList);
        });
    }

    /**
     * 根据角色id获取菜单权限
     * @param roleId
     * @return
     */
    @Override
    public List<Permission> findRolePermissionByRoleId(Long roleId) {
        // 获取所有菜单权限
        List<Permission> permissionList = baseMapper.selectList( null);
        // 获取当前角色已分配菜单权限, 根据角色id获取菜单权限
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId, roleId);
        List<RolePermission> rolePermissionList = rolePermissionService.list(wrapper);

        // 获取角色已分配菜单权限
        List<Long> permissionIdList = rolePermissionList.stream()
                .map(RolePermission::getPermissionId)
                .collect(Collectors.toList());

        // 存储角色已分配菜单权限
        List<Permission> assignPermissions = new ArrayList<>();
        for (Permission permission : permissionList) {
            if (permissionIdList.contains(permission.getId())) {
                assignPermissions.add(permission);
            }
        }
        logger.info("角色已分配菜单权限：{}", assignPermissions);
        return assignPermissions;
    }

    /**
     * 角色分配菜单权限
     * @param roleId
     * @param permissionId
     */
    @Override
    @Transactional
    public void saveRolePermission(Long roleId, List<Long> permissionId) {
        // 删除角色菜单权限
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId, roleId);
        rolePermissionService.remove(wrapper);
        // 添加角色菜单权限
        List<RolePermission> rolePermissionList = new ArrayList<>();
        for (Long id : permissionId) {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(id);
            rolePermissionList.add(rolePermission);
        }
        rolePermissionService.saveBatch(rolePermissionList);
    }
}
